
package com.example.filetransfer.publicsource.connection;

import com.example.filetransfer.publicsource.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class NetBroadcast extends Thread {
    private static final String TAG = "NetBroadcast";
    private static NetBroadcast sInstance = null;
    private List<MessageTask> mMessageSendTask = new ArrayList<MessageTask>();
    private ThreadState mState = ThreadState.NOT_INIT;
    private volatile boolean mStop = false;

    private class MessageTask {
        private int port;
        private String message;
    }

    public static synchronized NetBroadcast getInstance() {
        if (sInstance == null || sInstance.mState == ThreadState.STOPING
                || sInstance.mState == ThreadState.STOP) {
            sInstance = new NetBroadcast();
        }
        return sInstance;
    }

    private String mIp = null;
    public void setIp(String ip) {
        this.mIp = ip;
    }

    public void stopThread() {
        synchronized (mMessageSendTask) {
            mState = ThreadState.STOPING;
            mStop = true;
            mMessageSendTask.notify();
        }
    }

    public ThreadState getThreadState() {
        return mState;
    }

    private NetBroadcast() {
        this.start();
    }

    private MessageTask pullTask() {
        synchronized (mMessageSendTask) {
            if (mMessageSendTask.size() > 0) {
                return mMessageSendTask.remove(0);
            }
            return null;
        }
    }

    public void sendBroadcast(int port, String message) {
        synchronized (mMessageSendTask) {
            MessageTask messageTask = new MessageTask();
            messageTask.port = port;
            messageTask.message = message;
            mMessageSendTask.add(messageTask);
            mMessageSendTask.notify();
        }
    }

    @Override
    public void run() {
        while (!mStop) {
            synchronized (mMessageSendTask) {
                if (mMessageSendTask.size() <= 0) {
                    try {
                        mState = ThreadState.IDEL;
                        mMessageSendTask.wait();
                        if (mMessageSendTask.size() > 0) {
                            mState = ThreadState.WORKING;
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            MessageTask task = pullTask();
            if (task == null)
                continue;
            sendBroadcast(task);
        }
        mState = ThreadState.STOP;
    }

    protected DatagramSocket createDatagramSocket(int port) throws SocketException,
            UnknownHostException {
        if (mIp != null) {
            return new DatagramSocket(port, InetAddress.getByName(mIp));
        }
        return new DatagramSocket();
    }

    private void sendBroadcast(MessageTask task) {
        DatagramSocket client = null;
        String message = task.message;
        int port = task.port;
        try {
            byte[] msg = message.getBytes();
            Log.d(TAG, "send broadcast:" + message + " on port:" + port);
            InetAddress inetAddr = InetAddress.getByName("255.255.255.255");
            client = createDatagramSocket(port);
            DatagramPacket sendPack = new DatagramPacket(msg, msg.length, inetAddr,
                    port);
            client.send(sendPack);
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (client != null) {
                client.close();
            }
        }
    }

    public static void main(String[] args) {
        NetBroadcast.getInstance().sendBroadcast(10086, "WO RI NI MEI222");
    }
}
